evtchn: evtchn_reset() shouldn't succeed with still-open ports
authorJan Beulich <jbeulich@suse.com>
Tue, 22 Sep 2020 14:14:22 +0000 (16:14 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 22 Sep 2020 14:14:22 +0000 (16:14 +0200)
commit9b9fc8e391b6d5afa83f90271fdbd0e13871e841
treee578f60f2b9cd96abbf13271425139070f5de978
parentb8c2efbe7b3e8fa5f0b0a3679afccd1204949070
evtchn: evtchn_reset() shouldn't succeed with still-open ports

While the function closes all ports, it does so without holding any
lock, and hence racing requests may be issued causing new ports to get
opened. This would have been problematic in particular if such a newly
opened port had a port number above the new implementation limit (i.e.
when switching from FIFO to 2-level) after the reset, as prior to
"evtchn: relax port_is_valid()" this could have led to e.g.
evtchn_close()'s "BUG_ON(!port_is_valid(d2, port2))" to trigger.

Introduce a counter of active ports and check that it's (still) no
larger then the number of Xen internally used ones after obtaining the
necessary lock in evtchn_reset().

As to the access model of the new {active,xen}_evtchns fields - while
all writes get done using write_atomic(), reads ought to use
read_atomic() only when outside of a suitably locked region.

Note that as of now evtchn_bind_virq() and evtchn_bind_ipi() don't have
a need to call check_free_port().

This is part of XSA-343.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Julien Grall <jgrall@amazon.com>
xen/common/event_channel.c
xen/include/xen/sched.h